/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package xmlaufgabe7;

import java.io.IOException;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.XMLReaderFactory;

/**
 * SAX Parser Klasse zum Parsen eines XML Dokuments und Ueberprufung auf Validitaet
 * sowie der Form.
 * 
 * @author Adrian Cieluch
 */
public class SAXParser {
    /**
     * Speichert den Pfad des zu parsenden Dokumentes.
     */
    private String xmlDocument;
    /**
     * Speichert den Parser.
     */
    private XMLReader parser;
    
    /**
     * Speichert die InputQuelle.
     */
    private InputSource input;
    
    /**
     * Intiialisiert den Dateipfad und Parser mit uebergebenen Informationen.
     * 
     * @param file Dateipfad
     * @param parserInfo Erfolgreiche Parsererstellung
     */
    public SAXParser(String file, boolean parserInfo) {
        xmlDocument = (file == null) ? "" : file;
        parser = createParser(parserInfo);
    }
    
    /**
     * Initialisiert die Inputquelle und den DefaultHandler mit den uebergebenen
     * Informationen.
     * 
     * @param input Inputquelle
     * @param handler Ueberschriebener Defaulthandler
     * @param parserInfo Erfolgreiche Parsererstellung
     */
    public SAXParser(InputSource input, DefaultHandler handler, boolean parserInfo) {
        this.input = input;
        parser = createParser(parserInfo);
        if(parser != null && handler != null) {
            parser.setContentHandler(handler);
            parser.setDTDHandler(handler);
            parser.setErrorHandler(handler);
        }
    }
    
    /**
     * Initialisiert die Inputquelle und den DefaultHandler mit den uebergebenen
     * Informationen. Es werden standardmaessig keine Informationen ueber den
     * Erfolg der Parsererstellung ausgegeben.
     * 
     * @param input Inputquelle
     * @param handler Ueberschriebener Defaulthandler
     */
    public SAXParser(InputSource input, DefaultHandler handler) {
        this(input, handler, false);
    }
    
    /**
     * Konstruktor, initialisiert den Parser und setzt die Zusatzinformationen auf
     * false.
     * 
     * @param file Dateipfad
     */
    public SAXParser(String file) {
        this(file, false);
    }

    /**
     * Parst das XML Dokument auf wohl Geformtheit und bei Verlangen auch auf
     * Validitaet und gibt Informationen ueber Fehler oder Erfolg aus.
     * 
     * @param withInfo Parsen erfolgreich
     * @param withValidation Mit Validierung
     * @return (Miss)Erfolg des Parsens
     */
    public boolean parseXMLDocument(boolean withInfo, boolean withValidation) {
        boolean success = false;
        String text = "";
        if(parser != null) {
            try {
                if(withValidation) {
                    parser.setFeature("http://xml.org/sax/features/validation", true);
                }
                parser.parse(input);
                success = true;
                if(withInfo) {
                    text = "Das Dokument " + xmlDocument + " ist wohlgeformt.\n";
                    inform(text);
                }
            } catch(IOException ioe) {
                notifyError("IO Fehler: " + ioe.getMessage());
            } catch(SAXParseException saxpe) {
                text = "Das Dokument " + xmlDocument + " ist nicht " +
                        "wohlgeformt." + "\nFehler: " + saxpe.getMessage() +
                        "\nZeile: " + saxpe.getLineNumber() + 
                        "\nSpalte: " + saxpe.getColumnNumber() + "\n";
                notifyError(text);
            } catch(SAXException saxe) {
                text = "Beim Parsen des Dokuments " + xmlDocument + 
                        " ist ein Fehler aufgetreten.\nFehler: " +
                        saxe.getMessage() + "\n";
                notifyError(text);
            }
        } else {
            text = "Das Dokument " + xmlDocument + " wurde nicht geparst," +
                    " da kein Parser gefunden wurde.\n";
            notifyError(text);
        }
        
        return success;
    }
    
    /**
     * Erstellt einen Parser und gibt bei Verlangen eine Nachricht ueber den
     * Erfolg des Erstellens aus. Parser wird zurueck gegeben.
     * 
     * @param parserInfo Erstellung erfolgreich
     * @return erstellten Parser
     */
    private XMLReader createParser(boolean parserInfo) {
        XMLReader parser = null;
        String text = "";
        try {
            parser = XMLReaderFactory.createXMLReader();
            String name = parser.getClass().getName();
            if(parserInfo) {
                text = "Es wurde ein XMLReader vom Typ " + name + " erzeugt.\n";
                inform(text);
            }
        } catch(SAXException saxe) {
            text = "Fehler: Es konnte kein XMLReader erzeugt" +
                    "werden.\nGrund: " + saxe.getMessage() + "\n";
            notifyError(text);
        }
        
        return parser;
    }

    /**
     * Gibt Erfolg der Parsererstellung aus.
     * 
     * @param text Anzuzeigender Text
     */
    private void inform(String text) {
        System.out.println(text);
    }

    /**
     * Gibt Fehler aus.
     * 
     * @param info Fehlertext
     */
    private void notifyError(String info) {
        System.err.println(info);
    }
}
